using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LS.GameKit.Behaviour;
using UnityEngine.Events;

namespace LS.GameKit
{
    public abstract class TransformerBehaviour : GameBehaviourMono
    {
        public enum LoopType
        {
            Once,
            PingPong,
            Repeat
        }

        public LoopType loopType;

        public float duration = 1;
        public AnimationCurve accelCurve = AnimationCurve.EaseInOut(0,0,1,1);

        [SerializeField]
        private bool m_Activate = false;

        public UnityEvent OnStart = new UnityEvent();
        public UnityEvent OnStop = new UnityEvent();
        public UnityEvent<Vector3> OnDeltaPosition = new UnityEvent<Vector3>();
        public UnityEvent<Vector3> OnPositionChanged = new UnityEvent<Vector3>();

#if UNITY_EDITOR
        [Range(0, 1)]
        public float previewPosition;
#endif
        private float time = 0f;
        private float position = 0f;
        private float direction = 1f;

        public bool Activate
        {
            get
            {
                return m_Activate;
            }

            set
            {
                if (value) Play();
                else Stop();
            }
        }

        public float Position => position;

        public void Play()
        {
            m_Activate = true;
            OnStart?.Invoke();
        }

        public void Stop()
        {
            m_Activate = false;
            OnStop?.Invoke();
        }

        public void FixedUpdate()
        {
            if (m_Activate)
            {
                time = time + (direction * Time.deltaTime / duration);
                switch (loopType)
                {
                    case LoopType.Once:
                        LoopOnce();
                        break;
                    case LoopType.PingPong:
                        LoopPingPong();
                        break;
                    case LoopType.Repeat:
                        LoopRepeat();
                        break;
                }
                PerformTransform(position);
            }
        }

        public virtual void PerformTransform(float position)
        {

        }

        private void LoopPingPong()
        {
            position = Mathf.PingPong(time, 1f);
        }

        private void LoopRepeat()
        {
            position = Mathf.Repeat(time, 1f);
        }

        private void LoopOnce()
        {
            position = Mathf.Clamp01(time);
            if (position >= 1)
            {
                enabled = false;
                OnStop?.Invoke();
                direction *= -1;
            }
        }
    }
}
